import { Injectable, Logger } from "@nestjs/common";
import { WsException } from "@nestjs/websockets";
import * as fs from "fs-extra";
import * as path from "node:path";
import { Folder } from "src/common/model";

@Injectable()
export class FolderService {
    private readonly logger = new Logger(FolderService.name);

    constructor() {}

    async loadCurrentPath(dir: string): Promise<Folder> {
        dir = path.join(dir, path.sep);
        const stat = await fs.stat(dir);
        if (!stat.isDirectory()) {
            throw new WsException("路径不是文件夹");
        }

        const response: Folder = {
            name: path.parse(dir).name,
            absPath: dir,
            stats: {
                size: stat.size,
                atime: stat.atime,
                mtime: stat.mtime,
                ctime: stat.ctime,
                atimeMs: stat.atimeMs,
                mtimeMs: stat.mtimeMs,
                ctimeMs: stat.ctimeMs,
            },
            isDirectory: true,
        };

        try {
            const files = await fs.readdir(dir);
            response.childs = await Promise.all(
                files.map(async (name): Promise<Folder> => {
                    const absPath = path.join(dir, name);
                    try {
                        const stat = await fs.stat(absPath);
                        const isDirectory = stat.isDirectory();
                        return {
                            name,
                            absPath,
                            stats: {
                                size: stat.size,
                                atime: stat.atime,
                                mtime: stat.mtime,
                                ctime: stat.ctime,
                                atimeMs: stat.atimeMs,
                                mtimeMs: stat.mtimeMs,
                                ctimeMs: stat.ctimeMs,
                            },
                            isDirectory,
                        };
                    } catch (error) {
                        let isDirectory;
                        if (["EBUSY"].includes(error.code)) isDirectory = false;
                        return {
                            name,
                            absPath,
                            error: error.message,
                            isDirectory,
                        };
                    }
                }),
            );
            return response;
        } catch (error) {
            response.error = error.message;
            return response;
        }
    }
}
